package com.example.shiwu.util;

import static androidx.constraintlayout.motion.utils.Oscillator.TAG;

import android.util.Log;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class SocketBackUtils {

    public Socket socket = null;
    private static InputStream mInputStream = null;
    private static OutputStream mOutStream = null;
    private OnMessageReceivedListener messageListener;
    public static int success_count = 0;
    public static int header_cou = 0;
    public static String receiveDataAll = "";
    private String cmd_index_len = "";//消息的id 10
    public static Integer packet_lens = 0;
    public static Integer packet_indx = 0;
    public static int packet_lens_old = 0;
    private Boolean isReConnect = false;
    private int port = 8080;

    public static SocketReceiveThread mReceiveThread;
    public static SocketBackUtils instance;

    public static int receive_count = 0;
    public static String msg_0 = "";
    public static String msg_1 = "";
    //public byte[] buffer;


    public SocketBackUtils() {
        try {
            socket = new Socket(ContextVariable.IP, this.port);
            socket.setTcpNoDelay(true);
            // 启动心跳线程
            //socket.setKeepAlive(true);
//            SocketAddress socAddress = new InetSocketAddress(ContextVariable.IP, this.port);
//            socket.connect(socAddress, 5000);
            socket.setSoTimeout(5000);

            mInputStream = socket.getInputStream();
            mOutStream = socket.getOutputStream();
            writeMsg("22,M;");
            System.out.println("------------------socket 连接成功---------------");
        } catch (IOException e) {
            isReConnect = true;
            e.printStackTrace();
        }
    }
    public synchronized byte read(){

        byte[] buffer = new byte[1];
        try {
            mInputStream.read(buffer);
//            BufferedInputStream bis = new BufferedInputStream(mInputStream);
//            bis.read(buffer);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return buffer[0];
    }

    public static synchronized SocketBackUtils getInstance() {
        if(instance == null){
            instance = new SocketBackUtils();
        }
        return instance;
    }

    public void setOnMessageReceivedListener(OnMessageReceivedListener listener) {
        this.messageListener = listener;
    }

    public void startListening() {
        mReceiveThread = new SocketReceiveThread();
        mReceiveThread.start();
//        try {
//            mReceiveThread.join();
//        }catch (InterruptedException e) {
//            throw new RuntimeException(e);
//        }
    }


    public static void writeMsg(String msg) {
        //Log.i(TAG, "writeMsg msg=" + msg);
        if (msg.length() == 0 || mOutStream == null)
            return;
        try {
            mOutStream.write(msg.getBytes());//发送
            mOutStream.flush();
            //Log.i(TAG, "-----------------writeMsg msg ="+ msg);
           // Log.i(TAG, "-----------------writeMsg msg ="+ msg+"   success_count====="+success_count);


        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static void writeMsgByte(byte[] msg) {

//        Log.i(TAG, "------------------------------------------------writeMsgByte msg=" + msg +"mReceiveThread.isAlive() ="+mReceiveThread.getState());
//        Log.i(TAG, "------------------------------------------------writeMsgByte msg mOutStream=" + mOutStream);
        if (msg.length == 0 || mOutStream == null)
            return;
        try {
            mOutStream.write(msg);//发送
            mOutStream.flush();
            mReceiveThread.resumeThread();
            //Log.i(TAG, "-----------------writeMsgByte msg ="+ new String(msg,"iso8859-1")+"   success_count====="+success_count);

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public void closeConnection() {
        try {
            if (socket != null && !socket.isClosed()) {
                socket.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /*释放资源*/
    public  void releaseSocket(){
        if(mReceiveThread != null){
            mReceiveThread.threadExit =true;
            mReceiveThread = null;
        }


        instance = null;

        if (mOutStream != null) {
            try {
                mOutStream.close();

            } catch (IOException e) {
                e.printStackTrace();
            }
            mOutStream = null;
        }
        if(mInputStream!=null){
            try {
                mInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            mInputStream=null;
        }

        if (socket != null) {
            try {
                socket.close();

            } catch (IOException e) {
            }
            socket = null;
        }

        /*重新初始化socket*/
        if (isReConnect) {
            socket = null;
            mInputStream = null;
            mOutStream = null;
            new SocketBackUtils();
        }
    }

    public interface OnMessageReceivedListener {
        void onMessageReceived(byte message);
        void onMessageReceivedString(String message);

        void onConnectionLost();
    }

    public static void resumeThread(){
        mReceiveThread.resumeThread();
    }


    class SocketReceiveThread extends Thread {
        public final Object lock = new Object();
        public boolean threadExit;


        public SocketReceiveThread() {
            threadExit = false;
        }

        /**
         * 调用这个方法实现暂停线程
         */
        public void pauseThread() {
            threadExit = true;
        }

        /**
         * 调用这个方法实现恢复线程的运行
         */
        public void resumeThread() {
            threadExit = false;
            synchronized (lock) {
                lock.notifyAll();
            }
        }
        public void threadExit() {
            threadExit = true;
        }

        /**
         * 注意：这个方法只能在run方法里调用，不然会阻塞主线程，导致页面无响应
         */
        public void onPause() {
            synchronized (lock) {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

        @Override
        public void run() {
            System.out.println("-------threadExitrunrunrunrunrun == "+threadExit);
            String msg1 = "";
            while (threadExit == false) {
//                try {
//                    Thread.sleep(1);
//                } catch (InterruptedException e) {
//                    throw new RuntimeException(e);
//                }
//                writeMsg("13,update;");
//                System.out.println(" =============== 13,update;");
//                if(receive_count==1){
//                    this.onPause();
//                }
                //System.out.println("-------threadExit1111111111111111111111111 == ");
                try {
                    byte[] buffer = new byte[1];
                    //读取数据，返回值表示读到的数据长度。-1表示结束
                    int count = 0;
                    try {
                        //基于字符的读取或基于字节的读取
                        //System.out.println("---- buffer = "+buffer);
                        //if (mInputStream.available() > 0) { //添加这里的判断
                            //System.out.println("---- buffer = "+new String(buffer, "iso8859-1"));
                            count = mInputStream.read(buffer);
                            //int bytesRead = mInputStream.read(buffer);
                            if (count == -1) {
                                Log.i(TAG, "read -1");
                                break;
                            } else {
                                //System.out.println("---- buffer = "+buffer);

                                if (success_count <= 5) {
                                    String msg00 = new String(buffer, "utf-8");
                                    msg_0 += new String(buffer, "utf-8");
//                                    //System.out.println("---msg00 =" + msg00+" - "+buffer[0]);
                                    try {
                                        if(msg00.equals("??")){
                                            System.out.println("PC usb dis-connected");
                                            throw new Exception("PC usb dis-connected");
                                        }
                                    }catch (Exception e){
                                        e.printStackTrace();
                                    }
                                    String obj = receive_one_field(1);//过滤header
                                    String msg_all = msg_0 +=obj;
                                    //System.out.println("---msg_all =" + msg_all);

                                    if (msg_all.length() > 2) { //msg_all(0,success) len超过2 也就是0，就可以返回了
                                        if(!msg_all.equals("0,wait;")){
                                            success_count += 1;
                                        }
                                        messageListener.onMessageReceivedString(msg_all);
                                        msg_0 = "";
                                    }

                                } else if (success_count == 6) {
                                    msg_0 = new String(buffer, "iso8859-1");

                                    //System.out.println("---msg msg_0 =" + msg_0);
                                    try {
                                        if(msg_0.equals("??")){
                                            System.out.println("PC usb dis-connected");
                                            throw new Exception("PC usb dis-connected");
                                        }
                                    }catch (Exception e){
                                        e.printStackTrace();
                                    }
                                    String obj = receive_one_field(2);//过滤header
                                    String msg_all = msg_0 +=obj;
                                    //System.out.println("---msg_all11 =" + msg_all);
                                    String msg_all_last = msg_all.substring(msg_all.length()-1,msg_all.length());
                                    if (!msg_all_last.equals(";")){
                                        msg_1 += msg_all;
                                        continue;
                                    }
                                    if(msg_all_last.equals(";")) { //msg_all(10,8) 截取数据
                                        success_count += 1;
                                        msg_1 += msg_all;
                                        receiveDataAll += msg_1;
                                        //System.out.println("---receiveDataAll =" + receiveDataAll);
                                        if (success_count == 7) {
                                            cmd_index_len = DataParseUtil.getDataForHeaderIndex(receiveDataAll);
                                            packet_indx = Integer.valueOf(DataParseUtil.initPython(cmd_index_len.split(",")[1]));

                                            packet_lens = Integer.valueOf(DataParseUtil.initPython(cmd_index_len.split(",")[2]));
                                           // System.out.println("--------mReceiveThread22222  packet_indx=="+packet_indx+" = "+packet_lens+" = "+success_count);
                                            packet_lens_old = packet_lens;
                                            DataParseUtil.setPageLens(packet_lens);
                                            receiveDataAll = "";
                                        }
                                        msg_0 = "";
                                        msg_1="";
                                    }

                                } else {
                                    if (success_count == 7) {
                                        //Log.i("buffer","-------------success_count =7" );
                                        success_count += 1;
                                        this.onPause();
                                        continue;
                                    }
                                    if (success_count > 7) {
                                        //Log.i("buffer","-------------success_count >6 -----------= " + new String(buffer));
                                        //Log.i("buffer","-------------success_count >6 -----------= " + buffer[0]);
//                                        messageListener.onMessageReceived(buffer[0]);
//                                        buffer = null;
                                    }
                                }
                            }
                            //this.pauseThread();
                        //}else {
                            //this.pauseThread();
                        //}

                    }catch (Exception e){
                        e.printStackTrace();
                    }

                }catch (Exception e){
                    e.printStackTrace();
                }

            }
            //System.out.println("-------threadExit222222222222222222222222 == "+threadExit);
        }
    }
    byte[] toPrimitives(Byte[] oBytes)
    {
        byte[] bytes = new byte[oBytes.length];

        for(int i = 0; i < oBytes.length; i++) {
            bytes[i] = oBytes[i];
        }

        return bytes;
    }

    private synchronized String receive_one_field(int sta) throws InterruptedException, UnsupportedEncodingException {
        Map<String, Object> map = new HashMap<>();
        Boolean escaped = false;
        Boolean command_sep_found = false;
        ArrayList<Byte> one_field = new ArrayList<Byte>();
        Boolean timeout = false;
        Boolean bl = true;
        String msgbt ="";
        while (bl) {
            byte tmp = this.read();
            byte[] b = new byte[1];
            b[0] = tmp;
            if(sta == 1){
                msgbt += new String(b, "utf-8");
            }else {
                msgbt += new String(b, "iso8859-1");
            }

            if (escaped) {
                if (tmp == 44 || tmp == 59 || tmp == 47) {
                    one_field.add(tmp);
                    escaped = false;
                } else {
                    one_field.add(tmp);
                    escaped = false;
                }
            } else {
                if (tmp == 47) {
                    //遇到 / 就escaped = True 继续循环
                    escaped = true;
                } else if (tmp == 44) {
                    break;
                } else if (tmp == 59) {
                    command_sep_found = true;
                    break;
                } else {
                    one_field.add(tmp);
                }
            }

        }

        map.put("one_field", one_field);
        map.put("timeout", timeout);
        return msgbt;
    }

}


